#include <pthread.h>
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <unistd.h>

// 抢票
//int tickets = 100;
//void* TicketGrabbing(void* arg)
//{
//    const char* name = (char*)arg;
//    while(true)
//    {
//        if(tickets > 0)
//        {
//            usleep(10000);
//            printf("[%s] get a tickets, left: %d\n", name, tickets);
//            --tickets;
//        }
//        else 
//            break;
//    }
//    printf("%s quit\n", name);
//    delete[] name;
//    pthread_exit((void*)0);
//}
//
//
//
//int main()
//{
//    std::vector<pthread_t> threads;
//    for(int i = 1; i <= 4; i++)
//    {
//        char* name = new char[64];
//        snprintf(name, 64, "thread_%d", i);
//        pthread_t tid;
//        pthread_create(&tid, nullptr, TicketGrabbing, (void*)name);
//        threads.push_back(tid);
//    }
//    
//    for(auto& tid : threads)
//    {
//        pthread_join(tid, nullptr);
//    }
//    return 0;
//}




//int count = 0;
//void* Routine(void* arg)
//{
//    while(true)
//    {
//        count++;
//        sleep(1);
//    }
//    pthread_exit((void*)0);
//}
//
//int main()
//{
//    pthread_t tid;
//    pthread_create(&tid, nullptr, Routine, nullptr);
//    while(true)
//    {
//        std::cout << "count = " << count << std::endl;
//        sleep(1);
//    }
//    pthread_join(tid, nullptr);
//    return 0;
//}


static int glob = 0;
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;

void* threadFunc(void* args)
{
    int loops = *((int*)args);
    int loc, j;
    for(j = 0; j < loops; j++)
    {
        int s = pthread_mutex_lock(&mtx);
        if(s != 0)
            perror("pthread_mutex_lock");
        loc = glob;
        loc++;
        glob = loc;
        
        s = pthread_mutex_unlock(&mtx);
        if(s != 0)
            perror("pthread_mutex_unlock");
    }
    return nullptr;
}

int main(int argc, char* argv[])
{
    (void)argc;
    pthread_t t1, t2;
    int loops = std::stoi(argv[1]);
    int s = pthread_create(&t1, nullptr, threadFunc, &loops);
    if(s != 0)
        perror("pthread_create_1");
    s = pthread_create(&t2, nullptr, threadFunc, &loops);
    if(s != 0)
        perror("pthread_create_2");

    s = pthread_join(t1, nullptr);
    if(s != 0)
        perror("pthread_join_1");
    s = pthread_join(t2, nullptr);
    if(s != 0)
        perror("pthread_join_2");
    std::cout << "glob = " << glob << std::endl;
    return 0;
}


//static int glob = 0;
//
//
//void* threadFunc(void* args)
//{
//    int loops = *((int*)args);
//    int loc, j;
//    for(j = 0; j < loops; j++)
//    {
//        loc = glob;
//        loc++;
//        glob = loc;
//    }
//    return nullptr;
//}
//
//int main(int argc, char* argv[])
//{
//    (void)argc;
//    pthread_t t1, t2;
//    int loops = std::stoi(argv[1]);
//    int s = pthread_create(&t1, nullptr, threadFunc, &loops);
//    if(s != 0)
//        perror("pthread_create_1");
//    s = pthread_create(&t2, nullptr, threadFunc, &loops);
//    if(s != 0)
//        perror("pthread_create_2");
//
//    s = pthread_join(t1, nullptr);
//    if(s != 0)
//        perror("pthread_join_1");
//    s = pthread_join(t2, nullptr);
//    if(s != 0)
//        perror("pthread_join_2");
//
//    std::cout << "glob = " << glob << std::endl;
//    return 0;
//}

